package com.ruoyi.quartz.task;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.constant.LoanConstants;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import com.ruoyi.bizsys.domain.CreditAccount;
import com.ruoyi.bizsys.domain.DateBatchFailLoan;
import com.ruoyi.bizsys.domain.LoanIou;
import com.ruoyi.bizsys.service.IBatchJobMonitoringService;
import com.ruoyi.bizsys.service.ICreditAccountService;
import com.ruoyi.bizsys.service.IDateBatchFailLoanService;
import com.ruoyi.bizsys.service.ILoanIouService;
import com.ruoyi.business.service.IBLoanInfoService;
import com.ruoyi.business.service.IBatchDateJobService;
import com.ruoyi.business.service.impl.BLoanInfoServiceImpl;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 批量任务重跑
 *
 * @author ruoyi
 */
@Slf4j
@Component("batchJobRerun")
public class BatchJobRerun {
	
	@Autowired
	IBatchDateJobService batchDateJobService;
	
	@Autowired
	@Lazy
	IBLoanInfoService loanInfoService;
	
	@Autowired
    ICreditAccountService creditAccountService;
	
	@Autowired
	IDateBatchFailLoanService dateBatchFailLoanService;

	@Autowired
	RedissonClient redissonClient;
	
	@Autowired
    ILoanIouService loanIouService;
	
	@Autowired
    private RedisCache redisCache;
	
	@Autowired
	IBatchJobMonitoringService batchJobMonitoringService;

    public void runBatch() throws ParseException {
    	log.info("rerun跑批任务 Start>>>>>>>>>>");
    	Date nowBatchDate = new Date();
    	//当天日期
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(nowBatchDate);
    	//将时分秒置0
    	calendar.set(Calendar.HOUR_OF_DAY, 0);
    	calendar.set(Calendar.MINUTE, 0);
    	calendar.set(Calendar.SECOND, 0);
    	calendar.set(Calendar.MILLISECOND, 0);
    	//开始跑批
    	Date nowDate = calendar.getTime();
    	
    	//查询所有失败的借据
    	List<DateBatchFailLoan> list = batchDateJobService.getBatchJobFailRecord(DateUtils.dateTime(nowDate));
    	for(DateBatchFailLoan l:list) {
    		//执行借据跑批
        	LoanIou query = new LoanIou();
        	query.setCustNo(l.getCustNo());
        	query.setLoanSerialNo(l.getLoanSerialNo());
        	query.setState(UserConstants.BUSINESS_NORMAL);
        	List<LoanIou> loanList = loanIouService.selectLoanIouList(query);
        	if(loanList.size() == 1) {
        		LoanIou loan = loanList.get(0);
				//还款日
				Date repayDate = DateUtils.parseDate(loan.getRepayDate(), DateUtils.YYYY_MM_DD_SLASH);
				//未到还款日
				if (nowDate.before(repayDate)) {
					l.setFailState(BizConstants.DATE_BATCH_FAIL_STATUS_SUCCESS);
					dateBatchFailLoanService.updateDateBatchFailLoan(l);
					continue;
				}
        		this.loanIouRunBatch(loan, nowDate,l,repayDate);
        	}
    	}

        log.info("rerun跑批任务 End>>>>>>>>>>");
    }
    
    private void loanIouRunBatch(LoanIou loan,Date nowDate, DateBatchFailLoan l,Date repayDate) {
    	//锁住客户账户再操作
        String lockKey = LoanConstants.CUST_ACCOUNT_LOCK_KEY_PREFIX + loan.getCustNo();
		RLock lock = redisCache.lock(lockKey);
		try {
			//获取账户信息
			CreditAccount accountQuery = new CreditAccount();
			accountQuery.setCustNo(loan.getCustNo());
			accountQuery.setState(UserConstants.BUSINESS_NORMAL);
			List<CreditAccount> selectCreditAccountList = creditAccountService.selectCreditAccountList(accountQuery);
			if (selectCreditAccountList.size() < 1) {
				throw new BusinessException(RspEnmu.SYSTEM_SYSDATA_EXCEPTION);
			}
			CreditAccount account = selectCreditAccountList.get(0);
			long start = System.currentTimeMillis();
			//还款日
			//Date repayDate = DateUtils.parseDate(loan.getRepayDate(), DateUtils.YYYY_MM_DD_SLASH);

//			//未到还款日
//			if (nowDate.before(repayDate)) {
//				l.setFailState(BizConstants.DATE_BATCH_FAIL_STATUS_SUCCESS);
//				dateBatchFailLoanService.updateDateBatchFailLoan(l);
//				continue;
//			}

			//判断借据还款日是否大于跑批日-更新借据-并发起代扣
			if (nowDate.after(repayDate)) {
				//更新借据信息
				loan = loanInfoService.doLoanIouBatchJob(nowDate, loan);
			}

			//判断借据还款日是否等于当天-发起代扣
			//发起代扣申请记录
			//loanInfoService.createRepaymentOrder(loan, null, BizConstants.LOAN_REPAYMENT_ORDER_TYPE_DATE_BATCH);

			//更新账户信息
			loanInfoService.updateAccount(account);
			log.info("执行日批借据号{}更新成功", loan.getLoanSerialNo());

			//更新失败的状态
			l.setFailState(BizConstants.DATE_BATCH_FAIL_STATUS_SUCCESS);
			dateBatchFailLoanService.updateDateBatchFailLoan(l);
			long end = System.currentTimeMillis();
			log.info("锁占用时间，耗时：" + (end - start) + " ms");
			//无需重试
		} catch (Exception e) {
			log.error("执行日批借据号{}更新异常", loan.getLoanSerialNo(), e);
		} finally {
			lock.unlock();
		}
    }


}